//
//  AndroidTest.m
//  playin
//
//  Created by cj on 2019/7/9.
//  Copyright © 2019 lijunge. All rights reserved.
//

#import "AndroidTest.h"
#import "net/PISocket.h"
#import "PIVideoDecode.h"
#import "PIUtil.h"
#import <VideoToolbox/VideoToolbox.h>

@interface AndroidTest () <PISocketDelegate>
@property (nonatomic, strong) PISocket *socket;
@property (nonatomic, weak) PIVideoDecode *vDecode;
@end

@implementation AndroidTest {
    
    dispatch_queue_t delegateQueue;
}

- (instancetype)init {
    
    if (self = [super init]) {
        delegateQueue = dispatch_queue_create("tech.playin.pistream.test", NULL);
        self.socket = [[PISocket alloc] initWithDelegate:self delegateQueue:delegateQueue];
        NSData *sps = [PIUtil dataFromHexString:@"6742C0298D681705165E01E1108D40"];
        NSData *pps = [PIUtil dataFromHexString:@"68CE01A835C8"];
        self.vDecode = [PIVideoDecode shared];
        BOOL ret = [self.vDecode updateSps:sps pps:pps];
        NSLog(@"[AndroidTest] update xps ret: %d", ret);
    }
    return self;
}

- (void)start {
    
    NSError *error = nil;
    [self.socket connectToHost:@"103.192.215.38" onPort:2222 withTimeout:3 error:&error];
}

- (void)socketDidConnect:(PISocket *)sock {
    
    
}

- (void)socketDidDisconnect:(PISocket *)sock withError:(nullable NSError *)err {
    
}

- (void)socket:(PISocket *)sock didReadPacket:(NSData *)packet {
    
    //printf("[AndroidTest] %s\n", packet.description.UTF8String);
    pi_packet_t *pkt = (pi_packet_t*)packet.bytes;
    uint8_t stream_type = *(uint8_t *)(pkt->data);
    NSData * data = [NSData dataWithBytes:pkt->data + 1 length:pkt->length - 1];
    
    unsigned long avcc_len = [data length] - 4;
    
    uint32_t len2 = (uint32_t)CFSwapInt32BigToHost(avcc_len);
    NSMutableData *naluData = [[NSMutableData alloc] initWithBytes:&len2 length:4];
    [naluData appendData:[data subdataWithRange:NSMakeRange(4, avcc_len)]];
    
//    NSLog(@"nal = %@", naluData);
    
    uint8_t *ptr = (uint8_t *)data.bytes;
    uint8_t nalu_type = ptr[4] & 0x1F; // 前四字节是NALU长度码
    if (stream_type == pi_stream_h264) {
        if (nalu_type == 1) { // Coded slice of a non-IDR picture
            
            [self decodeSlice:naluData];
        } else if (nalu_type == 5) { // Coded slice of an IDR picture
            [self decodeSlice:naluData];
        }
    }
    return;
//    uint8_t *ptr = (uint8_t *)packet.bytes;
//
//    uint8_t nalu_type = ptr[10] & 0x1F; // 前四字节是NALU长度码
//    //uint8_t *nalu_ptr = (uint8_t *)packet.bytes+6; // video data
//    NSLog(@"[AndroidTest] nalu_type: %u", nalu_type);
//
//    @autoreleasepool {
//
//        if (nalu_type == 1) { // Coded slice of a non-IDR picture
//            //NSData *subData = [packet subdataWithRange:NSMakeRange(6, packet.length-6)];
//            NSData *subData2 = [packet subdataWithRange:NSMakeRange(10, packet.length-10)];
//            NSUInteger subData2Len = [subData2 length];
//            uint32_t subData2Len2 = (uint32_t)CFSwapInt32BigToHost(subData2Len);
//            NSMutableData *naluData = [[NSMutableData alloc] initWithBytes:&subData2Len2 length:4];
//            [naluData appendData:subData2];
//            NSLog(@"[AndroidTest] naluData: %@", naluData);
//            [self decodeSlice:naluData];
//        } else if (nalu_type == 5) { // Coded slice of an IDR picture
//            NSData *subData = [packet subdataWithRange:NSMakeRange(6, packet.length-6)];
//            NSData *subData2 = [packet subdataWithRange:NSMakeRange(10, packet.length-10)];
//            [self decodeSlice:subData2];
//        } else if (nalu_type == 6) { // Supplemental enhancement information (SEI)
//        } else if (nalu_type == 7) { // Sequence parameter set
//            //[self synthesizeAndUpdateParameterSet:packet];
//        } else if (nalu_type == 8) { // Picture parameter set
//            //[self synthesizeAndUpdateParameterSet:packet];
//        }
//    }
    
}

- (void)decodeSlice:(NSData *)slice {
    
    __weak typeof(self) weakSelf = self;
    [self.vDecode decodeData:slice completionHandle:^(CVImageBufferRef imageBuffer) {
        NSLog(@"[AndroidTest] imageBuffer: %@", imageBuffer);
        
        CVPixelBufferRetain(imageBuffer);
        UIImage *image = [self imageWithImageBuffer:imageBuffer];
        NSLog(@"[AndroidTest] image: %@", image);
        CVPixelBufferRelease(imageBuffer);
    }];
}

- (UIImage *)imageWithImageBuffer:(CVImageBufferRef)imageBuffer {
    
    UIImage *uiImage = nil;
    if (@available(iOS 9.0, *)) {
        CVPixelBufferRetain(imageBuffer);
        CGImageRef cgImage = nil;
        VTCreateCGImageFromCVPixelBuffer(imageBuffer, nil, &cgImage);
        uiImage = [UIImage imageWithCGImage:cgImage];
        CGImageRelease(cgImage);
        CVPixelBufferRelease(imageBuffer);
    } else {
        CVPixelBufferRetain(imageBuffer);
        CIImage *ciImage = [CIImage imageWithCVPixelBuffer:imageBuffer];
        CIContext *temporaryContext = [CIContext contextWithOptions:nil];
        CGRect imageRect = CGRectMake(0, 0, CVPixelBufferGetWidth(imageBuffer), CVPixelBufferGetHeight(imageBuffer));
        CGImageRef cgImage = [temporaryContext createCGImage:ciImage fromRect:imageRect];
        uiImage = [UIImage imageWithCGImage:cgImage];
        CGImageRelease(cgImage);
        CVPixelBufferRelease(imageBuffer);
    }
    
    return uiImage;
}

@end
